package com.class5.springboot.filter;

import com.class5.springboot.config.Audience;
import com.class5.springboot.config.ResultEnum;
import com.class5.springboot.entity.TbXtAction;
import com.class5.springboot.frame.repo.INormalRepository;
import com.class5.springboot.frame.repo.real.JwtService;
import com.class5.springboot.frame.security.RequestContext;
import com.class5.springboot.util.common.JwtHelper;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Repository;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Repository
public class JwtFilter extends GenericFilterBean {

    @Autowired
    private Audience audience;

    private JwtService jwtService;

    /**
     *  Reserved claims（保留），它的含义就像是编程语言的保留字一样，属于JWT标准里面规定的一些claim。JWT标准里面定好的claim有：

     iss(Issuser)：代表这个JWT的签发主体；
     sub(Subject)：代表这个JWT的主体，即它的所有人；
     aud(Audience)：代表这个JWT的接收对象；
     exp(Expiration time)：是一个时间戳，代表这个JWT的过期时间；
     nbf(Not Before)：是一个时间戳，代表这个JWT生效的开始时间，意味着在这个时间之前验证JWT是会失败的；
     iat(Issued at)：是一个时间戳，代表这个JWT的签发时间；
     jti(JWT ID)：是JWT的唯一标识。
     * @param req
     * @param res
     * @param chain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(final ServletRequest req, final ServletResponse res, final FilterChain chain)
            throws IOException, ServletException {
        final String HEADER_PARAM_NAME = "asstoken";

        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) res;
        //等到请求头信息authorization信息
        final String authHeader = request.getHeader(HEADER_PARAM_NAME);
        RequestContext context = null;

        if (authHeader == null || !authHeader.startsWith("token")) {
           throw new SecurityException("请在请求头信息中添加"+HEADER_PARAM_NAME+"参数，格式为'token:'+token信息");
        }
        final String token = authHeader.substring(6);
        if(audience == null){
            BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
            audience = (Audience) factory.getBean("audience");
        }
        final Claims claims = JwtHelper.parseJWT(token,audience.getBase64Secret());
        if(claims == null){
            throw new SecurityException(ResultEnum.LOGIN_ERROR);
        }
        //角色权限判断
        if(claims.get("role")==null){
            throw new SecurityException(ResultEnum.LOGIN_ERROR_NOROLE);
        }
//        Long roleid = Long.parseLong(claims.get("role")+"");
//        ServletContext servletContext = request.getServletContext();
//        ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
//        JwtService jwtService = ctx.getBean(JwtService.class);
//        jwtService.roleRuthority(roleid,request.getRequestURI());//判断有无权限调用该api
        request.setAttribute("claims", claims);
        chain.doFilter(req, res);
    }
}